// ---------------------------------------------------------------------------------------------------------------------------------
// VGUI Control File for PCMod
// [CLIENTSIDE]
// Revision: 1
// ---------------------------------------------------------------------------------------------------------------------------------

// ---------------------------------------------------------------------------------------------------------------------------------
// pc_initfonts: Initialise Hook: Creates all the fonts we need
// ---------------------------------------------------------------------------------------------------------------------------------
function pc_initfonts()
	surface.CreateFont( "Tahoma", 14, 400, false, false, "PCText" )
	surface.CreateFont( "System", 14, 400, false, false, "LetterText" )
	surface.CreateFont( "Tahoma", 14, 800, false, false, "PCTextBold" )
	surface.CreateFont( "Tahoma", 10, 400, false, false, "SmallPCText" )
end

// ---------------------------------------------------------------------------------------------------------------------------------
// pc_initsettings: Initialise Hook: Creates the settings window
// ---------------------------------------------------------------------------------------------------------------------------------
function pc_initsettings()
	// Setup the tabbed window
	DInterface:Setup( w*0.25, h*0.25, w*0.5, h*0.5, "PC Mod", true, false )
	
	// Add a settings tab
	DInterface:AddCategory( "CSettings", "Settings", "", "Settings" )
	DInterface:AddCheckbox( "cbFrame", "CSettings", "Enable Frame", 5, 5, ShouldDrawFrame )
	DInterface:AddSlider( "slFrameID", "CSettings", "FrameID", 5, 30, 100, 25, 1, 3, 0 )
	obj = DInterface:GetObject( "cbFrame", "cb", "CSettings" )
	if (obj) then obj:SetConVar( "pc_shoulddrawframe" ) end
	obj = DInterface:GetObject( "slFrameID", "s", "CSettings" )
	if (obj) then obj:SetConVar( "pc_frameid" ) end
	if (obj) then obj:SetValue( FrameID ) end
	DInterface:AddButton( "btnUpdate", "CSettings", "Update", 5, 75, 100, 20, function ()
		FrameID = CV_FRAME:GetInt()
		pc_loadframe(FrameID)
		pc_rebuildscreen()
	end )
		
	// Finish the tabbed window setup (this also enables adding controls to other stuff)
	DInterface:FinishSetup()
end


// ---------------------------------------------------------------------------------------------------------------------------------
// pc_draw: HUDPaint Hook: Draws relevant data upon looking at a PCMod Entity
// ---------------------------------------------------------------------------------------------------------------------------------
function pc_draw()
	// Check if we are looking at an entity
	local trace = {}
	trace.start = LocalPlayer():EyePos()
	trace.endpos = trace.start + LocalPlayer():GetAimVector() * 200
	trace.filter = LocalPlayer()
	local tr = util.TraceLine(trace)
	
	// Check if that entity is ours - if so, draw relevant info
	if (tr.Entity) and (!tr.HitWorld) then
		ent = tr.Entity
		if (ent.IsPC) then
			local status = StatusToString( PCBeam:GetBeamValue( ent, "Status" ) )
			local ip = PCBeam:GetBeamValue( ent, "IP" )
			local text = { "Standard PC", status, ip }
			
			if (ent.IsLaptop) then text = { "Laptop", status, ip } end
			
			pc_drawbubble( ScrW()*0.4, ScrH()*0.45, ScrW()*0.2, ScrH()*0.1, text )
		end
		if (ent.IsRouter) then
			local subnet = tostring( PCBeam:GetBeamValue( ent, "Subnet", 0 ) )
			local text = { "Network Router", "Subnet: " .. subnet }
			
			if (ent.SatRouter) then text[1] = "Satellite Modem" end
			if (ent.IsRepeater) then text[1] = "Network Repeater" end
			
			pc_drawbubble( ScrW()*0.4, ScrH()*0.475, ScrW()*0.2, ScrH()*0.05, text )
		end
		if (ent.IsServer) then
			local on = "Off"
			
			if (PCBeam:GetBeamValue( ent, "IsOn", false)) then on = "On" end
			
			local text = { "Server", PCBeam:GetBeamValue( ent, "AppName", "" ), on, PCBeam:GetBeamValue( ent, "IP", "192.168.0.1" ) }
			
			pc_drawbubble( ScrW()*0.4, ScrH()*0.45, ScrW()*0.2, ScrH()*0.1, text )
		end
		if (ent.IsPrinter) then
			local printing = "Not Printing"
			
			if (PCBeam:GetBeamValue( ent, "Printing", false )) then printing = "Printing" end
			
			local text = { "Printer", printing }
			
			pc_drawbubble( ScrW()*0.4, ScrH()*0.475, ScrW()*0.2, ScrH()*0.05, text )
		end
		if (ent.IsLetter) then
			local text = { "Printed Document" }
			
			pc_drawbubble( ScrW()*0.4, ScrH()*0.4875, ScrW()*0.2, ScrH()*0.025, text )
		end
		if (ent.IsDebug) then
			local val = tostring( PCBeam:GetBeamValue( ent, "MyNumber" ) )
			local text = { "Debugger", val }
			
			pc_drawbubble( ScrW()*0.4, ScrH()*0.475, ScrW()*0.2, ScrH()*0.05, text )
		end
		if (ent.IsSpeaker) then
			local playing = "Not Playing"
			
			if (PCBeam:GetBeamValue( ent, "Playing", false )) then playing = "Playing" end
			
			local text = { "Speaker", playing }
			
			if (ent.IsSplitter) then text = { "Sound Splitter" } end
			
			pc_drawbubble( ScrW()*0.4, ScrH()*0.475, ScrW()*0.2, ScrH()*0.05, text )
		end
	end
end
hook.Add( "HUDPaint", "PCMod_HUDPaint", pc_draw )

// ---------------------------------------------------------------------------------------------------------------------------------
// pc_drawbubble: Draws a bubble with relevant data
// ---------------------------------------------------------------------------------------------------------------------------------
function pc_drawbubble( x, y, width, height, text )
	draw.RoundedBox( 6, x, y, width, height, Color( 200, 255, 255, 128 ) )
	local heightperlabel = height/#text
	for i=1,#text do
		ypos = y + ((i-1)*heightperlabel)
		xpos = x + (width * 0.5)
		draw.SimpleText( text[i], "PCText", xpos, ypos, Color( 0, 0, 0, 255 ), 1, 3 )
	end
end

// ---------------------------------------------------------------------------------------------------------------------------------
// pc_setupscreen: Initialise Hook: Creates the derma window for the PC
// ---------------------------------------------------------------------------------------------------------------------------------
function pc_setupscreen()
	// Load the screen texture
	ScreenTexID = surface.GetTextureID( "vgui/pc_screen1" )
	
	// Create the host window
	local sw = w * 0.9
	local sh = h * 0.9
	PC_ScreenSizeX = sw
	PC_ScreenSizeY = sh
	DInterface:MakeWindow( "host", "PCMod Release V" .. PCMod.Version .. " - by [GU]|ZLC|thomasfn", (w-sw)/2, (h-sh)/2, sw, sh, false, false )
	DInterface:MakePanel( "pcscreen", WTC("host"), 0, 0, sw, sh, function( self )
		if (ShouldDrawFrame) then
			surface.SetTexture( FrameTex )
			surface.SetDrawColor( 255, 255, 255, 255 )
			surface.DrawTexturedRect( 0, 0, self:GetWide(), self:GetTall() )
		end
	end )
	
	// Create the 'desktop'
	local ss = pc_calcscreensize( sw, sh )
	local dw = ss[1]
	local dh = ss[2]
	local dx = ss[3]
	local dy = ss[4]
	
	DInterface:MakePanel( "desktop", PTC("pcscreen"), dx, dy, dw, dh, pc_paintdesktop )
		DInterface:AddButton( "turnon", PTC("pcscreen"), "Turn On", 5, sh-60, 100, 20, function() pc_command( "turn_on" ); end )
		DInterface:AddButton( "turnoff", PTC("pcscreen"), "Turn Off", 110, sh-60, 100, 20, function() pc_command( "turn_off" ); end )
		DInterface:AddButton( "closescreen", PTC("pcscreen"), "Close", 215, sh-60, 100, 20, function() pc_closescreen(); end )
		
	// Make a dummy panel for desktop icons
	// DInterface:MakePanel( "dicons", PTC("desktop"), 0, 0, dw, dh, function() end )
		
	// Create the window in which programs will run
	DInterface:MakePanel( "window", PTC("desktop"), 5, 5, dw-10, dh-30, pc_paintwindow )
	
	// Get the panel controls
	local desktop = DInterface:GetPanel( "desktop" )
	local window = DInterface:GetPanel( "window" )
	// local dicons = DInterface:GetPanel( "dicons" )
	PCMod.Desktop = desktop
	
	// Create the lower bar
	PCMod.LowerBar = vgui.Create( "LowerBar" )
	PCMod.LowerBar:SetParent( desktop )
	PCMod.LowerBar:SetPos( 0, desktop:GetTall()*0.94 )
	PCMod.LowerBar:SetSize( desktop:GetWide(), desktop:GetTall()*0.06 )
	PCMod.LowerBar:Setup()
	PCMod.LowerBar:SetVisible( false )
	
	// Create the start menu
	PCMod.StartMenu = vgui.Create( "StartMenu" )
	PCMod.StartMenu:SetParent( desktop )
	PCMod.StartMenu:SetPos( 0, desktop:GetTall()*0.25 )
	PCMod.StartMenu:SetSize( desktop:GetWide()*0.25, (desktop:GetTall()*0.75) - 20 )
	PCMod.StartMenu:Setup()
	PCMod.StartMenu:SetV( false )
	
	// Create the programs list
	PCMod.ProgramList = vgui.Create( "ProgramList" )
	PCMod.ProgramList:SetParent( desktop )
	PCMod.ProgramList.ParentHeight = desktop:GetTall()
	PCMod.ProgramList:SetPos( desktop:GetWide()*0.25, 0 )
	PCMod.ProgramList:SetWidth( desktop:GetWide()*0.2 )
	PCMod.ProgramList:SetV( false )
	
	// Create 'tools' icon
	PCMod.ToolsIcon = vgui.Create( "Icon" )
	PCMod.ToolsIcon:SetParent( window )
	PCMod.ToolsIcon:SetVisible( false )
	PCMod.ToolsIcon:SetSize( 20, 20 )
	PCMod.ToolsIcon:SetPos( window:GetWide()-40, 0 )
	PCMod.ToolsIcon:SetIcon( "icons/goldstar" )
	PCMod.ToolsIcon:EnableClick( pc_progtools )
end

// ---------------------------------------------------------------------------------------------------------------------------------
// pc_geticon: Returns the texture id of an icon, and stores it
// ---------------------------------------------------------------------------------------------------------------------------------
function pc_geticon( icon )
	if (!LoadedIcons[icon]) then
		LoadedIcons[icon] = surface.GetTextureID( icon )
	end
	return LoadedIcons[icon]
end

// ---------------------------------------------------------------------------------------------------------------------------------
// pc_paintdesktop: Draws the desktop of a PC
// ---------------------------------------------------------------------------------------------------------------------------------
function pc_paintdesktop( self )
	PCMod.LowerBar:SetVisible( false )
	// PCMod.
	local status = C_PC.Status
	if (status == 0) then
		// PC is Off
		surface.SetDrawColor( 0, 0, 0, 255 )
		surface.DrawRect( 0, 0, self:GetWide(), self:GetTall() )
		draw.SimpleText( "< PC OFF >", "PCText", self:GetWide()/2, self:GetTall()/2, Color(255, 255, 255, 255), 1, 1 )
	end
	if (status == 1) then
		// PC is Booting
		surface.SetDrawColor( 0, 0, 50, 255 )
		surface.DrawRect( 0, 0, self:GetWide(), self:GetTall() )
		draw.SimpleText( "Booting PC...", "PCText", self:GetWide()/2, self:GetTall()/2, Color(255, 255, 255, 255), 1, 1 )
	end
	if (status == 2) then
		// PC is requesting password
		surface.SetDrawColor( 128, 128, 255, 255 )
		surface.DrawRect( 0, 0, self:GetWide(), self:GetTall() )
		draw.RoundedBox( 6, self:GetWide()*0.2, self:GetTall()*0.35, self:GetWide()*0.6, self:GetTall()*0.25, Color( 50, 50, 50, 128 ) )
		draw.SimpleText( "Password Required", "PCText", self:GetWide()/2, self:GetTall()*0.375, Color(255, 255, 255, 255), 1, 1 )
		
		local txtPass = DInterface:GetObject( "txtPass", "tb", PTC("desktop") )
		local btnGo = DInterface:GetObject( "btnGo", "b", PTC("desktop") )
		if (!txtPass) then DInterface:AddTextbox( "txtPass", PTC("desktop"), "", (self:GetWide()*0.25), (self:GetTall()*0.42), (self:GetWide()*0.5), (self:GetTall()*0.08) ) end
		if (!btnGo) then DInterface:AddButton( "btnGo", PTC("desktop"), "Login", (self:GetWide()*0.25), (self:GetTall()*0.5), (self:GetWide()*0.5), (self:GetTall()*0.08), function()
			pass = DInterface:GetTextboxValue( "txtPass", PTC("desktop") )
			RunConsoleCommand( "pc_command", "enter_password", pass )
		end ) end
		
		btnGo = DInterface:GetObject( "btnGo", "b", PTC("desktop") )
		if (btnGo) then pc_hackbutton( btnGo ) end
	end
	if (status == 3) then
		// PC is On
		PCMod.LowerBar:SetVisible( true )
	
		// Get the Desktop Colour
		local r = PCBeam:GetBeamValue( CurrentPC, "OS_DesktopR", 128 )
		local g = PCBeam:GetBeamValue( CurrentPC, "OS_DesktopG", 128 )
		local b = PCBeam:GetBeamValue( CurrentPC, "OS_DesktopB", 255 )
		if (!r) then r = 128 end
		if (!g) then g = 128 end
		if (!b) then b = 255 end
		
		// Draw the desktop background
		surface.SetDrawColor( r, g, b, 255 )
		surface.DrawRect( 0, 0, self:GetWide(), self:GetTall() )
		
		// Update the system tray
		if (C_PC.Online) then
			pc_systray_commit( "connect" )
			pc_systray_unlink( "disconnect" )
		else
			pc_systray_commit( "disconnect" )
			pc_systray_unlink( "connect" )
		end
		if (PCBeam:GetBeamValue( CurrentPC, "Wireless" )) then
			pc_systray_commit( "transmit" )
		else
			pc_systray_unlink( "transmit" )
		end
	end
end

// ---------------------------------------------------------------------------------------------------------------------------------
// pc_hackmenuoption: Alters the paint function of a menu option to allow for icons (OBSOLETE)
// ---------------------------------------------------------------------------------------------------------------------------------
function pc_hackmenuoption( control )
	// Hack the menu option by adding our own functions to it, or overriding existing ones
	// (Code 'borrowed' from ASSMod :P)
	if (!control) then return end
	control.Paint = function( self )
		derma.SkinHook( "Paint", "MenuOption", self )
		
		if (self.Image) then
	 		surface.SetTexture( self.Image ) 
 			surface.SetDrawColor( 255, 255, 255, 255 ) 
 			surface.DrawTexturedRect( 2, (self:GetTall() - 16) * 0.5, 16, 16)
 		end
	end
end

// ---------------------------------------------------------------------------------------------------------------------------------
// pc_hackbutton: Alters the paint function of a button to call the theme hook
// ---------------------------------------------------------------------------------------------------------------------------------
function pc_hackbutton( control )
	// Hack the button by overriding the paint function
	if (!control) then return end
	control.Paint = function( self )
		CurrentTheme:DrawButton( 0, 0, self:GetWide(), self:GetTall(), self:IsDown() )
	end
end

// ---------------------------------------------------------------------------------------------------------------------------------
// pc_paintwindow: Draws the window of a program
// ---------------------------------------------------------------------------------------------------------------------------------
function pc_paintwindow( self )
	if (!C_PRO) then C_PRO = {} end
	if (C_PRO.Exists) then
		// We have a program up and running
		// Draw the background
		CurrentTheme:DrawBackground( 0, 0, self:GetWide(), self:GetTall() )
		
		// Draw the title bar
		local txt = C_PRO.NiceName .. " - " .. C_PRO.Author
		CurrentTheme:DrawProgramBar( 0, 0, self:GetWide(), 20, txt )
		
		// Draw the icon
		local ico = C_PRO.Icon
		if (!ico) then ico = "icons/ico_app" end
		surface.SetTexture( pc_geticon( "vgui/" .. ico ) )
		surface.SetDrawColor( 255, 255, 255, 255 )
		surface.DrawTexturedRect( 0, 0, 20, 20 )
	end
end

// ---------------------------------------------------------------------------------------------------------------------------------
// pc_maketoolinfo: Turns a standard derma label control into an information box
// ---------------------------------------------------------------------------------------------------------------------------------
function pc_maketoolinfo( ctrl, title, desc )
	local p = ctrl:GetParent()
	ctrl:SetText( "" )
	ctrl.Paint = function( self )
		draw.RoundedBox( 6, 0, 0, self:GetWide(), self:GetTall(), Color( 50, 50, 50, 200 ) )
		draw.SimpleText( title, "PCTextBold", 3, 3, Color( 255, 255, 255, 255 ), TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP )
		draw.SimpleText( desc, "PCText", 3, 23, Color( 255, 255, 255, 255 ), TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP )
	end
	ctrl.PerformLayout = function( self )
		self:SetHeight( 40 )
	end
	if (p) then
		local x, y = ctrl:GetPos()
		ctrl:SetSize( p:GetWide()-10, 50 )
		ctrl:SetPos( 5, y )
	end
end